home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / lapbtime.c < prev    next >
C/C++ Source or Header  |  1993-07-30  |  3KB  |  150 lines

  1. /* LAPB (AX.25) timer recovery routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9. #include "timer.h"
  10. #include "lapb.h"
  11.  
  12. static void tx_enq __ARGS((struct ax25_cb *axp));
  13.  
  14. int lapbtimertype = 0;        /* default to binary exponential */
  15.  
  16. /* Called whenever timer T1 expires */
  17. void
  18. recover(p)
  19. void *p;
  20. {
  21.     register struct ax25_cb *axp = (struct ax25_cb *)p;
  22.  
  23.     axp->flags.retrans = 1;
  24.     axp->retries++;
  25.  
  26.     switch(lapbtimertype){
  27.         case 2:             /* original backoff mode*/
  28.             set_timer(&axp->t1,axp->srt * 2);
  29.             break;
  30.         case 1:             /* linear backoff mode */
  31.             if((1L << axp->retries) < Blimit)
  32.                 set_timer(&axp->t1,dur_timer(&axp->t1) + axp->srt);
  33.             break;
  34.         case 0:             /* exponential backoff mode */
  35.             if((1L << axp->retries) < Blimit)
  36.                 set_timer(&axp->t1,dur_timer(&axp->t1)*2);
  37.             break;
  38.     }
  39.  
  40.  
  41.     switch(axp->state){
  42.     case LAPB_SETUP:
  43.         if(axp->n2 != 0 && axp->retries > axp->n2){
  44.             nr_derate(axp);
  45.             free_q(&axp->txq);
  46.             axp->reason = LB_TIMEOUT;
  47.             lapbstate(axp,LAPB_DISCONNECTED);
  48.         } else {
  49.             sendctl(axp,LAPB_COMMAND,SABM|PF);
  50.             start_timer(&axp->t1);
  51.         }
  52.         break;
  53.     case LAPB_DISCPENDING:
  54.         if(axp->n2 != 0 && axp->retries > axp->n2){
  55.             nr_derate(axp);
  56.             axp->reason = LB_TIMEOUT;
  57.             lapbstate(axp,LAPB_DISCONNECTED);
  58.         } else {
  59.             sendctl(axp,LAPB_COMMAND,DISC|PF);
  60.             start_timer(&axp->t1);
  61.         }
  62.         break;
  63.     case LAPB_CONNECTED:
  64.     case LAPB_RECOVERY:
  65.         if(axp->n2 != 0 && axp->retries > axp->n2){
  66.             /* Give up */
  67.             nr_derate(axp);
  68.             sendctl(axp,LAPB_RESPONSE,DM|PF);
  69.             free_q(&axp->txq);
  70.             axp->reason = LB_TIMEOUT;
  71.             lapbstate(axp,LAPB_DISCONNECTED);
  72.         } else {
  73.             /* Transmit poll */
  74.             tx_enq(axp);
  75.             lapbstate(axp,LAPB_RECOVERY);
  76.         }
  77.         break;
  78.     }
  79. }
  80.  
  81.  
  82. /* Send a poll (S-frame command with the poll bit set) */
  83. void
  84. pollthem(p)
  85. void *p;
  86. {
  87.     register struct ax25_cb *axp;
  88.  
  89.     axp = (struct ax25_cb *)p;
  90.     if(axp->proto == V1)
  91.         return;    /* Not supported in the old protocol */
  92.     switch(axp->state){
  93.     case LAPB_CONNECTED:
  94.         axp->retries = 0;
  95.         tx_enq(axp);
  96.         lapbstate(axp,LAPB_RECOVERY);
  97.         break;
  98.     }
  99. }
  100.  
  101. /* Called whenever timer T4 (link rudundancy timer) expires */
  102. void
  103. redundant(p)
  104. void *p;
  105. {
  106.     register struct ax25_cb *axp;
  107.  
  108.     axp = (struct ax25_cb *)p;
  109.     switch(axp->state){
  110.     case LAPB_CONNECTED:
  111.     case LAPB_RECOVERY:
  112.         axp->retries = 0;
  113.         sendctl(axp,LAPB_COMMAND,DISC|PF);
  114.         start_timer(&axp->t1);
  115.         free_q(&axp->txq);
  116.         lapbstate(axp,LAPB_DISCPENDING);
  117.         break;
  118.     }
  119. }
  120.  
  121. /* Transmit query */
  122. static void
  123. tx_enq(axp)
  124. register struct ax25_cb *axp;
  125. {
  126.     char ctl;
  127.     struct mbuf *bp;
  128.  
  129.     /* I believe that retransmitting the oldest unacked
  130.      * I-frame tends to give better performance than polling,
  131.      * as long as the frame isn't too "large", because
  132.      * chances are that the I frame got lost anyway.
  133.      * This is an option in LAPB, but not in the official AX.25.
  134.      */
  135.     if(axp->txq != NULLBUF
  136.      && (len_p(axp->txq) < axp->pthresh || axp->proto == V1)){
  137.         /* Retransmit oldest unacked I-frame */
  138.         dup_p(&bp,axp->txq,0,len_p(axp->txq));
  139.         ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1)
  140.          | (axp->vr << 5);
  141.         sendframe(axp,LAPB_COMMAND,ctl,bp);
  142.     } else {
  143.         ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  144.         sendctl(axp,LAPB_COMMAND,ctl);
  145.     }
  146.     axp->response = 0;    
  147.     stop_timer(&axp->t3);
  148.     start_timer(&axp->t1);
  149. }
  150.